home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_2 / interfaces / guispell-1.3 / guispell.c < prev    next >
C/C++ Source or Header  |  1993-04-21  |  20KB  |  697 lines

  1. /*
  2.  *  This is GUISpell, the GadTool Front End for ISpell.
  3.  *  You must have AmigaOS release 2.04 (with ARexx running) and
  4.  *  `ISpell Version 3.1ljr with ARexx Server Mode, Thu Dec 27 04:16:35 1990'
  5.  *  or later.
  6.  *
  7.  *  Special thanks to Mike Schwartz for his PD GadTools Example
  8.  *  that was posted to alt.sources.amiga on `11 Nov 91 12:14:43 PST'
  9.  *  <mykes.8924@amiga0.SF-Bay.ORG>.  You will note that some chunks
  10.  *  below were ripped right out of his PD posting.  Thanks!
  11.  *  [Note: I don't like names that shout at me, so I removed all the
  12.  *   loud typedefs... :-]
  13.  *
  14.  *  Thanks to Eddy Carroll for Small.a (I now use cres.o, but thanks).
  15.  *  Thanks to Michael Jansson for smallIFFparse (a sub-set of IFFparse
  16.  *  that is Freely Redistributable) and sample code.
  17.  *
  18.  *  This program makes use of many 2.04 features and may be used as
  19.  *  an example of how to use iffparse.library, gadtools.library,
  20.  *  MinRexx (by Radical Eye Software, Thanks!), clipboard hooks,
  21.  *  public screen features and commodities.library.
  22.  *
  23.  *  This work is Copyright © 1991, 1992  Loren J. Rittle (rittle@comm.mot.com)
  24.  *  This software may be freely distributed and redistributed,
  25.  *  for non-commercial purposes, provided this notice is included.
  26.  *  You have the right to use the information contained within this
  27.  *  document/program in any way that you see fit, as long as you quote
  28.  *  this as the source of the information.  You have the right to compile
  29.  *  and run the program that is generated for any purpose.  All other
  30.  *  rights (most notably commercial ones) are reserved by the author.
  31.  *
  32.  *  DISCLAIMER:
  33.  * "This software is provided 'as-is', without warranty of any kind,
  34.  *  either expressed or implied.  In no event will I, Loren J. Rittle,
  35.  *  be liable for direct, indirect, incidental or consequential damages
  36.  *  or data loss resulting from the use or application of this software.
  37.  *  The entire risk as to the results and performance of this software
  38.  *  is assumed by you."
  39.  *
  40.  *  This program is distributed in the hope that it will be useful,
  41.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  42.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  43.  *
  44.  *  There, how's that for legal mush? :-)  Just trying to cover my...
  45.  *
  46.  *  Loren J. Rittle
  47.  *  rittle@comm.mot.com
  48.  *  Sun Dec 08 21:19:13 1991
  49.  *
  50.  *  Modified by Eric G. Suchanek, Ph.D. to handle larger screen default fonts
  51.  *  so that the gadgets don't end up in the window border 11/22/92
  52.  *
  53.  */
  54.  
  55. #include <string.h>
  56. #pragma msg 148 ignore push
  57. #pragma msg 149 ignore push
  58. #pragma msg 61 ignore push
  59. #include <devices/clipboard.h>
  60. #include <proto/all.h>
  61. #pragma msg 149 pop
  62. #pragma msg 61 pop
  63. #include "libraries.h"
  64. #include "error.h"
  65. #include "minrexx.h"
  66. #include "textclip.h"
  67.  
  68. extern long __builtin_getreg (int);
  69. extern void __builtin_putreg (int, long);
  70. #define REG_A4 12
  71.  
  72. extern char *_ProgramName;
  73.  
  74. #define VERSION "GUISpell 1.3 (21.4.93)"
  75. #define NICE_VERSION "GUISpell-1.3 (" __DATE__ " " __TIME__ ")"
  76.  
  77. static char Version_ID[] = "$VER: " VERSION;
  78.  
  79. char *listText[512];
  80. char *initListText[] =
  81. {
  82.   NICE_VERSION,
  83.   "This is a freely distributable version",
  84.   "Copyright \xa9 1991, 1992  Loren J. Rittle",
  85.   "",
  86.   "GUISpell is the premier GUI front-end",
  87.   "to ISpell 3.3LJR (or later) with ARexx",
  88.   "Server Mode, for AmigaOS Release 2.04.",
  89.   "",
  90.   "If you use this software, please mail",
  91.   "the author at rittle@comm.mot.com, so I",
  92.   "can inform you of bugs and upgrades.",
  93.   0,
  94. };
  95.  
  96. struct List lvList;
  97. struct Gadget *gList;
  98. struct Window *window;
  99. struct Screen *screen;
  100. APTR vi;
  101. void *memory;
  102. struct IOClipReq *ClipReq;
  103. struct MsgPort *ClipPort;
  104. struct Hook ClipHook;
  105. struct ClipHookMsg ClipHookMsg = {0, CMD_UPDATE, 0};
  106. struct Task *Task;
  107. ULONG ClipAlertSignalNum = -1;
  108. BOOL done;
  109. int auto_clip;
  110. int lookup_type;
  111.  
  112. struct TextAttr topaz80 = {"topaz.font", 8, 0, 0};
  113.  
  114. char *cycleText[] = {"Spell", "Reg exp", "Exact", 0};
  115.  
  116. struct TagItem nullTags[] = {TAG_DONE, 0};
  117. struct TagItem cycleTags[] = {GTCY_Labels, (int) &cycleText[0], GTBB_Recessed, FALSE, TAG_DONE, 0};
  118. struct TagItem listviewTags[] = {GTLV_Labels, (int) &lvList, GTLV_ReadOnly, FALSE, GTLV_ScrollWidth, 16, TAG_DONE, 0};
  119. struct TagItem stringTags[] = {GTTX_CopyText, TRUE, GTTX_Border, FALSE, TAG_DONE, 0};
  120.  
  121. struct
  122. {
  123.   struct TagItem *tags;
  124.   ULONG kind;
  125.   UWORD left, top, width, height;
  126.   ULONG flags;
  127.   char *text;
  128.   struct Gadget *object;
  129. } gads[] =
  130. {
  131.   {cycleTags, CYCLE_KIND, 121, 3, 90, 12, NG_HIGHLABEL, "Lookup Style:", 0},
  132.   {nullTags, CHECKBOX_KIND, 310, 3, 80, 12, NG_HIGHLABEL, "Auto-Clip:", 0},
  133.   {listviewTags, LISTVIEW_KIND, 20, 34, 360, 92, NG_HIGHLABEL | PLACETEXT_ABOVE, "", 0},
  134.   {nullTags, BUTTON_KIND, 234, 18, 81, 12, NG_HIGHLABEL | PLACETEXT_IN,"From Clip", 0},
  135.   {nullTags, BUTTON_KIND, 325, 18, 65, 12, NG_HIGHLABEL | PLACETEXT_IN,"To Clip", 0},
  136.   {nullTags, BUTTON_KIND, 350, 3, 40, 12, NG_HIGHLABEL | PLACETEXT_IN,"Add", 0},
  137.   {stringTags, STRING_KIND, 10, 18, 180, 12, NG_HIGHLABEL, "", 0},
  138.   {nullTags, BUTTON_KIND, 200, 18, 24, 12, NG_HIGHLABEL | PLACETEXT_IN,"Do", 0},
  139.   {0, 0, 0, 0, 0, 0, 0, 0, 0},
  140. };
  141.  
  142. #define    LOOKUP_STYLE_ID    0
  143. #define    AUTO_CLIP_ID    1
  144. #define    WORD_LIST_ID    2
  145. #define FROM_CLIP_ID    3
  146. #define TO_CLIP_ID    4
  147. #define ADD_WORD_ID    5
  148. #define USER_WORD_ID    6
  149. #define DO_ID        7
  150.  
  151. int main (int argc, char *argv[]);
  152. void SubmitCheckRequest (int type, char *word);
  153. void UpdateList (struct RexxMsg *msg);
  154. void ProcessGadget (UWORD id, UWORD code);
  155. void GadgetUp (struct IntuiMessage *m);
  156. void *CreateList (struct List *list, char *array[]);
  157. struct Gadget *CreateGadgets (int);
  158. void OpenAll (void);
  159. void CloseAll (void);
  160. void rexxdisp (struct RexxMsg *msg, struct rexxCommandList *dat, char *p);
  161.  
  162. void rexxjump (struct RexxMsg *msg, char *p);
  163. void rexxcheck (struct RexxMsg *msg, char *p);
  164. /* void rexxquickcheck (struct RexxMsg *msg, char *p);
  165. //void rexxlookup (struct RexxMsg *msg, char *p);
  166. //void rexxcheckmode (struct RexxMsg *msg, char *p);
  167. //void rexxautomode (struct RexxMsg *msg, char *p);
  168. //void rexxzoommode (struct RexxMsg *msg, char *p);
  169. //void rexxzoomwindow (struct RexxMsg *msg, char *p); */
  170. void rexxcurrenttext (struct RexxMsg *msg, char *p);
  171. void rexxcheckcallbackhook (struct RexxMsg *msg, char *p);
  172. void invokerexxcheckcallbackhook (void);
  173. void rexxversion (struct RexxMsg *msg, char *p);
  174. void rexxexit (struct RexxMsg *msg, char *p);
  175.  
  176. struct rexxCommandList rcl[] =
  177. {
  178.   {"check", &rexxcheck},
  179.   {"jump", &rexxjump},
  180.   {"currenttext", &rexxcurrenttext},
  181.   {"checkcallbackhook", &rexxcheckcallbackhook},
  182.   {"version", &rexxversion},
  183.   {"exit", &rexxexit},
  184.   {NULL, NULL}
  185. };
  186.  
  187. /* This is really kludged up to get it to work under SAS/C 6.2
  188.    with cres.o.  This code is unportable between compilers and
  189.    in fact may fail with other versions of SAS/C.  */
  190. ULONG __asm ClipChange (register __a0 struct Hook *hook,
  191.             register __a4 void *junk)
  192. {
  193.   __builtin_putreg (REG_A4, (long) hook->h_SubEntry);
  194.   Signal (Task, 1 << ClipAlertSignalNum);
  195.   return 0;
  196. }
  197.  
  198. int main (int argc, char *argv[])
  199. {
  200.   long rexxbit;
  201.  
  202.   OnError (&CloseAll);
  203.  
  204.   {
  205.     int i;
  206.  
  207.     for (i = 0; initListText[i]; i++)
  208.       listText[i] = initListText[i];
  209.   }
  210.  
  211.   OpenAll ();
  212.  
  213.   if (!(rexxbit = upRexxPort ("GUISpell", rcl, 0, &rexxdisp)))
  214.     Error ("ss", _ProgramName, ": MinRexx had a problem.\n");
  215.  
  216.   while (!done)
  217.     {
  218.       struct IntuiMessage *m;
  219.       long returnbits = Wait ((1 << window->UserPort->mp_SigBit) | rexxbit |
  220.                   (1 << ClipAlertSignalNum) | SIGBREAKF_CTRL_C);
  221.  
  222.       if (returnbits & SIGBREAKF_CTRL_C)
  223.     done = 1;
  224.       if (returnbits & rexxbit)
  225.     dispRexxPort ();
  226.       if ((returnbits & (1 << ClipAlertSignalNum)) && auto_clip)
  227.     {
  228.           char buffer[256];
  229.  
  230.           if (TextFromClip (buffer, 256) && !strchr (buffer, ' '))
  231.         {
  232.           static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  233.  
  234.           tags[0].ti_Data = (ULONG) buffer;
  235.           GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  236.           SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  237.         }
  238.     }
  239.       if (returnbits & (1 << window->UserPort->mp_SigBit))
  240.         while (m = GT_GetIMsg (window->UserPort))
  241.       {
  242.         struct IntuiMessage msg = *m;
  243.         GT_ReplyIMsg (m);
  244.  
  245.         switch (msg.Class)
  246.           {
  247.           case IDCMP_GADGETUP:
  248.         if (msg.Code == 0x09)
  249.           {
  250.           }
  251.         if (msg.Code == 0x5f)
  252.           {
  253.           }
  254.         else
  255.           ProcessGadget (((struct Gadget *) msg.IAddress)->GadgetID, msg.Code);
  256.             break;
  257.  
  258.           case IDCMP_REFRESHWINDOW:
  259.             GT_BeginRefresh (window);
  260.             GT_EndRefresh (window, TRUE);
  261.             break;
  262.  
  263.           case IDCMP_CLOSEWINDOW:
  264.             done = 1;
  265.             break;
  266.  
  267.           default:
  268.             break;
  269.           }
  270.       }
  271.     }
  272.  
  273.   CloseAll ();
  274.   return 0;
  275. }
  276.  
  277. void SubmitCheckRequest (int lookup_type, char *word)
  278. {
  279.   char buffer[256];
  280.   static char *rexxcommandname[] = {"check ", "lookup ", "quickcheck ", "add "};
  281.  
  282.   if (lookup_type > 3)
  283.     {
  284.       DisplayBeep (0);
  285.       return;
  286.     }
  287.   strcpy (buffer, rexxcommandname[lookup_type]);
  288.   strncat (buffer, word, 240);
  289.   if (!sendSimpleCmd (buffer, "IRexxSpell", &UpdateList, NULL, NULL, NULL))
  290.     DisplayBeep (0);
  291. }
  292.  
  293. void UpdateList (struct RexxMsg *msg)
  294. {
  295.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  296.   static struct TagItem tags2[] = {GTLV_Labels, (int) &lvList, GTLV_Top, 0, TAG_DONE, 0};
  297.   static char buffer[513];
  298.  
  299.   if (!msg->rm_Result1 && msg->rm_Result2)
  300.     {
  301.       GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  302.  
  303.       if (((struct RexxArg *) (msg->rm_Result2-8))->ra_Length > 512)
  304.     {
  305.           memcpy (buffer, (char *) msg->rm_Result2, 512);
  306.       buffer[512] = '\0';
  307.     }
  308.       else
  309.     {
  310.           memcpy (buffer, (char *) msg->rm_Result2,
  311.           ((struct RexxArg *) (msg->rm_Result2-8))->ra_Length);
  312.           buffer[((struct RexxArg *) (msg->rm_Result2-8))->ra_Length] = '\0';
  313.     }
  314.  
  315.       {
  316.     int a, b = 0;
  317.  
  318.     listText[b++] = &buffer[0];
  319.     for (a = 0; buffer[a]; a++)
  320.       if (buffer[a] == ' ')
  321.         {
  322.           if (buffer[a+1])
  323.         listText[b++] = &buffer[a+1];
  324.           buffer[a] = '\0';
  325.         }
  326.     listText[b] = 0;
  327.       }
  328.       
  329.       if (memory)
  330.         {
  331.           FreeVec (memory);
  332.           memory = 0;
  333.         }
  334.       memory = CreateList (&lvList, &listText[0]);
  335.  
  336.       GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags2);
  337.  
  338.       DeleteArgstring ((char *) msg->rm_Result2);
  339.     }
  340.   else
  341.     DisplayBeep (0);
  342. }
  343.  
  344. void ProcessGadget (UWORD id, UWORD code)
  345. {
  346.   switch (id)
  347.     {
  348.     case LOOKUP_STYLE_ID:
  349.       lookup_type = code;
  350.       break;
  351.     case AUTO_CLIP_ID:
  352.       auto_clip = gads[id].object->Flags & SELECTED;
  353.       break;
  354.     case WORD_LIST_ID:
  355.      {
  356.       static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  357.       tags[0].ti_Data = (ULONG) listText[code];
  358.       GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  359.       if (auto_clip)
  360.     TextToClip (((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  361.       invokerexxcheckcallbackhook ();
  362.       break;
  363.      }
  364.     case FROM_CLIP_ID:
  365.      {
  366.       char buffer[256];
  367.  
  368.       if (TextFromClip (buffer, 256))
  369.     {
  370.       static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  371.  
  372.       tags[0].ti_Data = (ULONG) buffer;
  373.       GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  374.       if (!strchr (buffer, ' '))
  375.         SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  376.     }
  377.       break;
  378.      }
  379.     case TO_CLIP_ID:
  380.       TextToClip (((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  381.       break;
  382.     case ADD_WORD_ID:
  383.       SubmitCheckRequest (3, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  384.       break;
  385.     case DO_ID:
  386.     case USER_WORD_ID:
  387.       SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  388.       break;
  389.     default:
  390.       break;
  391.     }
  392. }
  393.  
  394. void *CreateList (struct List *list, char *array[])
  395. {
  396.   short i;
  397.   struct Node *np, *start_np;
  398.  
  399.   NewList (list);
  400.   for (i = 0; array[i]; i++)
  401.     ;
  402.   start_np = AllocVec (sizeof (struct Node) * i, 0);
  403.   if (!start_np)
  404.     Error ("ss", _ProgramName, ": No free memory!\n");
  405.  
  406.   for (i = 0, np = start_np; array[i]; i++, np++)
  407.     {
  408.       np->ln_Name = (APTR) array[i];
  409.       np->ln_Pri = 0;
  410.       AddTail (list, np);
  411.     }
  412.   return start_np;
  413. }
  414.  
  415. struct Gadget *CreateGadgets (int top)
  416. {
  417.   struct Gadget *gadget, *glist = 0;
  418.   short i;
  419.   struct NewGadget ng;
  420.  
  421.   gadget = CreateContext (&glist);
  422.   if (!gadget)
  423.     Error ("ss", _ProgramName, ": Can't CreateContext\n");
  424.   for (i = 0; gads[i].tags; i++)
  425.     {
  426.       ng.ng_GadgetID = i;
  427.       ng.ng_TextAttr = &topaz80;
  428.       ng.ng_VisualInfo = vi;
  429.       ng.ng_LeftEdge = gads[i].left;
  430.       ng.ng_TopEdge = gads[i].top + top;
  431.       ng.ng_Width = gads[i].width;
  432.       ng.ng_Height = gads[i].height;
  433.       ng.ng_GadgetText = gads[i].text;
  434.       ng.ng_Flags = gads[i].flags;
  435.       gads[i].object = gadget = CreateGadgetA (gads[i].kind, gadget, &ng, gads[i].tags);
  436.       if (!gadget)
  437.     Error ("ss", _ProgramName, ": Can't CreateGadget\n");
  438.     }
  439.   return glist;
  440. }
  441.  
  442.  
  443. void OpenAll (void)
  444. {
  445.   static int top = 0;
  446.  
  447.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  448.   static WORD zoom_data[4] = {0, 0, 400, 43};
  449.   static struct TagItem wtags[] =
  450.     {
  451.       WA_Left, 0, WA_Top, 0 /*set below*/,
  452.       WA_InnerWidth, 400, WA_InnerHeight, 130,
  453.       WA_MinWidth, 400, WA_MinHeight, 43, WA_MaxWidth, -1, WA_MaxHeight, -1,
  454.       WA_DetailPen, 0, WA_BlockPen, 3, WA_IDCMP, 
  455.       IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|BUTTONIDCMP|CYCLEIDCMP|LISTVIEWIDCMP,
  456.       WA_Gadgets, 0 /*set below*/, WA_PubScreen, 0, /*set below*/
  457.       WA_Title, (ULONG)"GUISpell-1.3", WA_SuperBitMap, 0,
  458.       WA_SizeGadget, FALSE, WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  459.       WA_CloseGadget, TRUE, WA_Backdrop, FALSE, WA_ReportMouse, FALSE,
  460.       WA_Borderless, FALSE, WA_Activate, TRUE, WA_RMBTrap, FALSE,
  461.       WA_AutoAdjust, TRUE,
  462.       WA_SimpleRefresh, TRUE, WA_Zoom, (ULONG)zoom_data, WA_RMBTrap, TRUE, TAG_DONE, 0
  463.     };
  464.  
  465.   OpenLibraries ();
  466.  
  467.   screen = LockPubScreen ("CygnusEdScreen1");
  468.   if (!screen)
  469.     screen = LockPubScreen ("Workbench");
  470.   if (!screen)
  471.     Error ("ss", _ProgramName, ": Can't Lock WB Screen!\n");
  472.  
  473.   vi = GetVisualInfoA (screen, TAG_DONE);
  474.   if (!vi)
  475.     Error ("ss", _ProgramName, ": Can't GetVisualInfoA\n");
  476.  
  477.   memory = CreateList (&lvList, &listText[0]);
  478.  
  479.   top = screen->WBorTop + (screen->Font->ta_YSize + 1);
  480.  
  481.   gList = CreateGadgets (top);
  482.   wtags[1].ti_Data = (ULONG) screen->BarHeight + 1;
  483.   wtags[11].ti_Data = (ULONG) gList;
  484.   wtags[12].ti_Data = (ULONG) screen;
  485.   window = OpenWindowTagList (NULL, wtags);
  486.   UnlockPubScreen (0, screen);
  487.   if (!window)
  488.     Error ("ss", _ProgramName, ": Can't open window\n");
  489.  
  490.  
  491.   GT_RefreshWindow (window, NULL);
  492.   GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  493.  
  494.   Task = FindTask (0);
  495.   if ((ClipAlertSignalNum = AllocSignal (-1)) == -1)
  496.     Error ("ss", _ProgramName, ": Can't get a signal\n");
  497.   if (!(ClipPort = CreatePort (0L, 0L)))
  498.     Error ("ss", _ProgramName, ": Can't create port\n");
  499.   if (!(ClipReq = (struct IOClipReq *) CreateExtIO (ClipPort, sizeof (*ClipReq))))
  500.     Error ("ss", _ProgramName, ": Can't create ExtIO\n");
  501.   if (OpenDevice ("clipboard.device", 0L, (struct IORequest *) ClipReq, 0L))
  502.     Error ("ss", _ProgramName, ": Can't open clipboard device\n");
  503.   ClipReq->io_Command = CBD_CHANGEHOOK;
  504.   ClipReq->io_Length = 1;
  505.   ClipReq->io_Data = (void *) &ClipHook;
  506.   ClipHook.h_Entry = (unsigned long (*)()) &ClipChange;
  507.   ClipHook.h_SubEntry = (ULONG (*)()) __builtin_getreg (REG_A4);
  508.   ClipHook.h_Data = &ClipHookMsg;
  509.   if (DoIO ((struct IORequest *) ClipReq))
  510.     Error ("ss", _ProgramName, ": Can't install clipboard hook\n");
  511. }
  512.  
  513. void CloseAll (void)
  514. {
  515.   struct IntuiMessage *msg;
  516.  
  517.   if (ClipReq)
  518.     {
  519.       ClipReq->io_Command = CBD_CHANGEHOOK;
  520.       ClipReq->io_Length = 0;
  521.       ClipReq->io_Data = (void *) &ClipHook;
  522.       if (DoIO ((struct IORequest *) ClipReq))
  523.         Warning ("ss", _ProgramName, ": Can't deinstall clipboard hook (crash soon... :-)\n");
  524.       if (ClipReq->io_Device)
  525.         CloseDevice ((struct IORequest *)ClipReq);
  526.       DeleteExtIO ((struct IORequest *)ClipReq);
  527.     }
  528.   if (ClipPort)
  529.     DeletePort (ClipPort);
  530.   if (ClipAlertSignalNum != -1)
  531.     FreeSignal (ClipAlertSignalNum);
  532.  
  533.   dnRexxPort ();
  534.  
  535.   if (window)
  536.     {
  537.       while (msg = (struct IntuiMessage *) GT_GetIMsg (window->UserPort))
  538.     GT_ReplyIMsg (msg);
  539.       CloseWindow (window);
  540.       window = 0;
  541.     }
  542.  
  543.   if (vi)
  544.     {
  545.       FreeVisualInfo (vi);
  546.       vi = 0;
  547.     }
  548.  
  549.   if (gList)
  550.     {
  551.       FreeGadgets (gList);
  552.       gList = 0;
  553.     }
  554.  
  555.   if (memory)
  556.     {
  557.       FreeVec (memory);
  558.       memory = 0;
  559.     }
  560.  
  561.   CloseLibraries ();
  562. }
  563.  
  564. void rexxdisp (struct RexxMsg *msg, struct rexxCommandList *dat, char *p)
  565. {
  566.   (*(dat->userdata)) (msg, p);
  567. }
  568.  
  569. void rexxjump (struct RexxMsg *msg, char *p)
  570. {
  571.   static int top = 0;
  572.   struct IntuiMessage *Imsg;
  573.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  574.   static WORD zoom_data[4] = {0, 0, 400, 43};
  575.   static struct TagItem wtags[] =
  576.     {
  577.       WA_Left, 0, WA_Top, 0 /*set below*/,
  578.       WA_InnerWidth, 400, WA_InnerHeight, 130,
  579.       WA_MinWidth, 400, WA_MinHeight, 43, WA_MaxWidth, -1, WA_MaxHeight, -1,
  580.       WA_DetailPen, 0, WA_BlockPen, 3, WA_IDCMP, 
  581.       IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|BUTTONIDCMP|CYCLEIDCMP|LISTVIEWIDCMP,
  582.       WA_Gadgets, 0 /*set below*/, WA_PubScreen, 0, /*set below*/
  583.       WA_Title, (ULONG)"GUISpell-1.3", WA_SuperBitMap, 0,
  584.       WA_SizeGadget, FALSE, WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  585.       WA_CloseGadget, TRUE, WA_Backdrop, FALSE, WA_ReportMouse, FALSE,
  586.       WA_Borderless, FALSE, WA_Activate, TRUE, WA_RMBTrap, FALSE,
  587.       WA_AutoAdjust, TRUE,
  588.       WA_SimpleRefresh, TRUE, WA_Zoom, (ULONG)zoom_data, WA_RMBTrap, TRUE, TAG_DONE, 0
  589.     };
  590.  
  591.   if (window)
  592.     {
  593.       while (Imsg = (struct IntuiMessage *) GT_GetIMsg (window->UserPort))
  594.     GT_ReplyIMsg (Imsg);
  595.       CloseWindow (window);
  596.       window = 0;
  597.     }
  598.  
  599.   if (vi)
  600.     {
  601.       FreeVisualInfo (vi);
  602.       vi = 0;
  603.     }
  604.  
  605.   if (gList)
  606.     {
  607.       FreeGadgets (gList);
  608.       gList = 0;
  609.     }
  610.  
  611.  
  612.   screen = LockPubScreen (p);
  613.   if (!screen)
  614.     screen = LockPubScreen ("Workbench");
  615.   if (!screen)
  616.     Error ("ss", _ProgramName, ": Can't Lock WB Screen!\n");
  617.  
  618.   vi = GetVisualInfoA (screen, TAG_DONE);
  619.   if (!vi)
  620.     Error ("ss", _ProgramName, ": Can't GetVisualInfoA\n");
  621.  
  622.   top = screen->WBorTop + (screen->Font->ta_YSize + 1);
  623.  
  624.   gList = CreateGadgets (top);
  625.   wtags[1].ti_Data = (ULONG) screen->BarHeight + 1;
  626.   wtags[11].ti_Data = (ULONG) gList;
  627.   wtags[12].ti_Data = (ULONG) screen;
  628.   window = OpenWindowTagList (NULL, wtags);
  629.   UnlockPubScreen (0, screen);
  630.   if (!window)
  631.     Error ("ss", _ProgramName, ": Can't open window\n");
  632.   GT_RefreshWindow (window, NULL);
  633.   GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  634. }
  635.  
  636. void rexxcheck (struct RexxMsg *msg, char *p)
  637. {
  638.   static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  639.  
  640.   tags[0].ti_Data = (ULONG) p;
  641.   GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  642.   SubmitCheckRequest (0, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  643.   replyRexxCmd (msg, 0L, 0L, "ok");
  644. }
  645.  
  646. void rexxcurrenttext (struct RexxMsg *msg, char *p)
  647. {
  648.   replyRexxCmd (msg, 0L, 0L, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  649. }
  650.  
  651. char checkcallbackhookcode[512];
  652.  
  653. void rexxcheckcallbackhook (struct RexxMsg *msg, char *p)
  654. {
  655.   if (!checkcallbackhookcode[0] || (strlen (p) < sizeof (checkcallbackhookcode)))
  656.     {
  657.       strcpy (checkcallbackhookcode, p);
  658.       replyRexxCmd (msg, 0L, 0L, "installed");
  659.     }
  660.   else
  661.     replyRexxCmd (msg, 0L, 0L, "notinstalled");
  662. }
  663.  
  664. void invokerexxcheckcallbackhook (void)
  665. {
  666.   if (checkcallbackhookcode[0] && !asyncRexxCmd (checkcallbackhookcode))
  667.     DisplayBeep (0);
  668.   checkcallbackhookcode[0] = '\0';
  669. }
  670.  
  671. void rexxversion (struct RexxMsg *msg, char *p)
  672. {
  673.   char buf[512];
  674.   int bufend = strlen(Version_ID+6);
  675.   int namesize;
  676.   int i;
  677.  
  678.   strcpy(buf, Version_ID+6);
  679.   buf[bufend++] = '\n';
  680.   for (i = 0; rcl[i].name != NULL; i++)
  681.     {
  682.       namesize = strlen(rcl[i].name);
  683.       if ((namesize + bufend) > 511)
  684.     break;
  685.       strcpy (&(buf[bufend++]), " ");
  686.       strcpy (&(buf[bufend]), rcl[i].name);
  687.       bufend += namesize;
  688.     }
  689.   replyRexxCmd (msg, 0L, 0L, buf);
  690. }
  691.  
  692. void rexxexit (struct RexxMsg *msg, char *p)
  693. {
  694.   done = 1;
  695.   replyRexxCmd (msg, 0L, 0L, "bye");
  696. }
  697.